package com.tennis.tennisreservation.repository;

import com.tennis.tennisreservation.entity.Order;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

/**
 * 订单数据仓库接口
 * 提供订单数据的存取操作
 */
@Repository
public interface OrderRepository extends JpaRepository<Order, Long> {
    
    /**
     * 根据用户ID查询订单列表
     * @param userId 用户ID
     * @return 订单列表
     */
    List<Order> findByUserId(Long userId);
    
    /**
     * 根据用户ID查询订单并分页
     * @param userId 用户ID
     * @param pageable 分页参数
     * @return 分页订单数据
     */
    Page<Order> findByUserId(Long userId, Pageable pageable);
    
    /**
     * 根据场地ID查询订单
     * @param courtId 场地ID
     * @return 订单列表
     */
    List<Order> findByCourtId(Long courtId);
    
    /**
     * 根据支付状态查询订单
     * @param payStatus 支付状态
     * @return 订单列表
     */
    List<Order> findByPayStatus(String payStatus);
    
    /**
     * 根据创建日期范围查询订单
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 订单列表
     */
    @Query("SELECT o FROM Order o WHERE o.createTime BETWEEN :startDate AND :endDate")
    List<Order> findByCreateTimeBetween(@Param("startDate") LocalDateTime startDate, @Param("endDate") LocalDateTime endDate);
    
    /**
     * 根据预约日期范围和时间段查询订单
     * 用于检查场地在某个时间段是否已被预约
     * @param courtId 场地ID
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 符合条件的订单列表
     */
    @Query("SELECT o FROM Order o WHERE o.courtId = :courtId AND " +
           "((o.startTime <= :endTime AND o.endTime >= :startTime))")
    List<Order> findConflictOrders(@Param("courtId") Long courtId, 
                                    @Param("startTime") LocalDateTime startTime, 
                                    @Param("endTime") LocalDateTime endTime);
    
    /**
     * 根据预约日期查询订单
     * @param date 预约日期
     * @return 订单列表
     */
    @Query("SELECT o FROM Order o WHERE DATE(o.startTime) = :date")
    List<Order> findByDate(@Param("date") LocalDate date);
    
    /**
     * 查询用户ID和关键词（模糊匹配订单ID）
     * @param userId 用户ID
     * @param keyword 关键词
     * @param pageable 分页参数
     * @return 分页订单数据
     */
    @Query("SELECT o FROM Order o WHERE o.userId = :userId AND CAST(o.id AS string) LIKE %:keyword%")
    Page<Order> findByUserIdAndKeyword(@Param("userId") Long userId, @Param("keyword") String keyword, Pageable pageable);
    
    /**
     * 根据订单状态查询订单
     * @param status 订单状态
     * @return 订单列表
     */
    List<Order> findByStatus(String status);
    
    /**
     * 根据用户ID和订单状态查询订单
     * @param userId 用户ID
     * @param status 订单状态
     * @return 订单列表
     */
    List<Order> findByUserIdAndStatus(Long userId, String status);
    
    /**
     * 根据用户ID和订单状态查询订单并分页
     * @param userId 用户ID
     * @param status 订单状态
     * @param pageable 分页参数
     * @return 分页订单数据
     */
    Page<Order> findByUserIdAndStatus(Long userId, String status, Pageable pageable);
    
    /**
     * 根据支付状态和订单状态查询订单
     * @param payStatus 支付状态
     * @param status 订单状态
     * @return 订单列表
     */
    List<Order> findByPayStatusAndStatus(String payStatus, String status);
} 